#include <string.h>
#include "buffer.h"

Buffer::Buffer(void)
:frame(*(Frame*)buffer)
,user(buffer + HEADER_HEAD_LENGTH)
,data(buffer + HEADER_DATA_INDEX)
{
	clear();
}
void Buffer::clear(void)
{
	length = 0;
	//memset(buffer, 0, sizeof(buffer));
}
void Buffer::push(uint8_t c)
{
	if(length < 0xffff)
	{
		buffer[length++] = c;
	}
}
void Buffer::pop(void)
{
	if(length > 0)
	{
		memmove(buffer, buffer+1, --length);
	}
}
bool Buffer::check(void)
{
	switch(frame.checkHeader(length))
	{
		case  1: break;
		case  0: return false;
		case -1: pop();return false;
	}
	switch(frame.checkFrame(length))
	{
		case  1: return true;
		case  0: return false;
		case -1: pop(); return false;
	}
	return false;
}
bool Buffer::make(void)
{
	uint16_t len = length - sizeof(Header);

	if(frame.header.L1 != len)
	{
		frame.dataLength(len);
	}
	if(frame.checkHeader() == false)
	{
		return false;
	}
	uint8_t cs = 0;
	uint8_t *p = user;

	for(int i = 0; i < frame.header.L1; i++)
	{
		cs += *p++;
	}
	*p++ = cs;
	*p = HEADER_FIX_ENDING;
	length += 2;
	return true;
}
bool Buffer::append(void* d, int len)
{
	uint8_t *p = (uint8_t*)d;

	for(int i = 0; i < len; i++)
	{
		push(p[i]);
	}
	return (len > 0);
}
uint16_t Buffer::dataLength(void)const
{
	int len = HEADER_DATA_INDEX + HEADER_TAIL_LENGTH;

	if(frame.sequence.TPV)
	{
		len += sizeof(AUXTime);
	}
	return length - len;
}
string  Buffer::toString(void)const
{
	string s;
	char buf[8];

	for(int i = 0; i < length; i++)
	{
		snprintf(buf, sizeof(buf), " %02X", buffer[i]);
		s += buf;
	}
	return s;
}
